home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 81
/
PCMania CD81_1.iso
/
PCMANIA
/
demosc81
/
raytrac.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-04-22
|
5KB
|
185 lines
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <i86.h>
#include <string.h>
#include <math.h>
#include "vesalint.h"
#include "affine.c"
#pragma aux Set_Mode=\
"int 10h"\
modify [ax]\
parm [ax]
int offset=0;
typedef struct RT_camera
{
float xpos,ypos,zpos,d;
}RT_CAMERA;
typedef struct RT_esfera
{
float xpos,ypos,zpos,radi;
float coeff;
VECTOR ambient,diffuse,specular;
}RT_ESFERA;
typedef struct RT_luz
{
float xpos,ypos,zpos;
VECTOR color;
}RT_LUZ;
typedef struct RT_escena
{
int num_luz,num_esfera,num_camera;
RT_ESFERA *esferas;
RT_LUZ *luces;
RT_CAMERA *cameras;
VECTOR ambient;
}RT_ESCENA;
void RT_render(RT_ESCENA *esc, unsigned char *dest)
{
int xc,yc,sc,ppos,min_esfera;
float bpart,disc,t1,t2,min_t;
VECTOR ray,color;
ppos=0;
for (sc=0;sc<esc->num_esfera;sc++)
esc->esferas[sc].coeff=pow(esc->cameras->xpos-esc->esferas[sc].xpos,2)+
pow(esc->cameras->ypos-esc->esferas[sc].ypos,2)+
pow(esc->cameras->zpos-esc->esferas[sc].zpos,2)-
pow(esc->esferas[sc].radi,2);
for (yc=-100;yc<100;yc++)
{
for (xc=-160;xc<160;xc++)
{
min_t=1000000.0;
min_esfera=-1;
ray.v1=xc;
ray.v2=yc;
ray.v3=esc->cameras->d;
ray=unit_vtr(ray);
for (sc=0;sc<esc->num_esfera;sc++)
{
bpart=(esc->cameras->xpos-esc->esferas[sc].xpos)*ray.v1+
(esc->cameras->ypos-esc->esferas[sc].ypos)*ray.v2+
(esc->cameras->zpos-esc->esferas[sc].zpos)*ray.v3;
disc=pow(bpart,2)-esc->esferas[sc].coeff;
if (disc>0)
{
disc=sqrt(disc);
t1=-bpart+disc;
t2=-bpart-disc;
if ((t1>0)&&(t1<min_t))
{
min_t=t1;
min_esfera=sc;
}
if ((t2>0)&&(t2<min_t))
{
min_t=t2;
min_esfera=sc;
}
}
}
if (min_esfera>=0)
{
color.v1=esc->esferas[min_esfera].ambient.v1*esc->ambient.v1;
color.v2=esc->esferas[min_esfera].ambient.v2*esc->ambient.v2;
color.v3=esc->esferas[min_esfera].ambient.v3*esc->ambient.v3;
dest[ppos ]=min(color.v3,254);
dest[ppos+1]=min(color.v2,254);
dest[ppos+2]=min(color.v1,254);
}
else
{
dest[ppos ]=0;
dest[ppos+1]=0;
dest[ppos+2]=0;
}
ppos+=3;
}
}
}
RT_ESCENA *ray_testing;
unsigned char *Virtpant1;
void main(int argc, char *argv[])
{
float movi=0;
ray_testing=malloc(sizeof(RT_ESCENA));
ray_testing->num_esfera =2;
ray_testing->num_camera =1;
ray_testing->num_luz =0;
ray_testing->esferas=malloc(sizeof (RT_ESFERA)*ray_testing->num_esfera);
ray_testing->cameras=malloc(sizeof (RT_CAMERA)*ray_testing->num_camera);
ray_testing->luces =malloc(sizeof (RT_LUZ )*ray_testing->num_luz);
ray_testing->ambient.v1=128;
ray_testing->ambient.v2=128;
ray_testing->ambient.v3=128;
ray_testing->esferas[0].xpos=100;
ray_testing->esferas[0].ypos=0;
ray_testing->esferas[0].zpos=950;
ray_testing->esferas[0].radi=100;
ray_testing->esferas[0].ambient.v1=1;
ray_testing->esferas[0].ambient.v2=0;
ray_testing->esferas[0].ambient.v3=0;
ray_testing->esferas[1].xpos=-100;
ray_testing->esferas[1].ypos=0;
ray_testing->esferas[1].zpos=1000;
ray_testing->esferas[1].radi=150;
ray_testing->esferas[1].ambient.v1=0;
ray_testing->esferas[1].ambient.v2=0;
ray_testing->esferas[1].ambient.v3=1;
ray_testing->cameras[0].xpos=0;
ray_testing->cameras[0].ypos=0;
ray_testing->cameras[0].zpos=0;
ray_testing->cameras[0].d=256;
Virtpant1=malloc(320*200*3);
Active.Screen.Width=320;
Active.Screen.Height=200;
Active.Screen.bpp=24;
if(argc>=2)
{
Active.Screen.bpp=atoi(argv[1]);
if (atoi(argv[1])==-1)
Active.Screen.Height=400;
}
Active.Work.Width=320;
Active.Work.Height=200;
Active.Work.bpp=24;
Active.EnableLFB=1;
if (!InitSetMode())return;
while (!kbhit())
{
ray_testing->esferas[0].xpos=200*cos(movi/20);
movi++;
RT_render(ray_testing,Virtpant1);
Flip(Virtpant1);
}
getch();
Free_Memory();
Set_Mode(0x3);
}